import os
import json
from datetime import datetime
from flask import Flask, request, jsonify, render_template

# 导入模块
from config_manager import config, save_config, CONFIG_FILE
from database_manager import create_tables, get_db_connection
from analysis_manager import generate_stock_analysis, analysis_status
from stock_data_provider import process_stock_symbol

app = Flask(__name__)

# 配置静态文件目录
app.static_folder = 'static'

# API端点
@app.route('/api/config', methods=['GET', 'POST'])
def handle_config():
    if request.method == 'GET':
        return jsonify(config)
    elif request.method == 'POST':
        new_config = request.json
        config.update(new_config)
        save_config(config)
        return jsonify({"status": "success", "message": "配置已更新"})


@app.route('/api/stocks/all', methods=['GET'])
def get_all_stocks_from_db():
    """从数据库获取所有股票信息，如果数据库连接失败则返回备用数据"""
    # 备用股票数据
    fallback_stocks = [
        {'symbol': '600519.SS', 'symbol_standardized': '600519', 'stock_name': '贵州茅台', 'industry': '白酒'},
        {'symbol': '000858.SZ', 'symbol_standardized': '000858', 'stock_name': '五粮液', 'industry': '白酒'},
        {'symbol': '002594.SZ', 'symbol_standardized': '002594', 'stock_name': '比亚迪', 'industry': '新能源汽车'},
        {'symbol': '601318.SS', 'symbol_standardized': '601318', 'stock_name': '中国平安', 'industry': '保险'},
        {'symbol': '600036.SS', 'symbol_standardized': '600036', 'stock_name': '招商银行', 'industry': '银行'},
        {'symbol': '000002.SZ', 'symbol_standardized': '000002', 'stock_name': '万科A', 'industry': '房地产'},
        {'symbol': '600000.SS', 'symbol_standardized': '600000', 'stock_name': '浦发银行', 'industry': '银行'},
        {'symbol': '000725.SZ', 'symbol_standardized': '000725', 'stock_name': '京东方A', 'industry': '电子'},
        {'symbol': '601166.SS', 'symbol_standardized': '601166', 'stock_name': '兴业银行', 'industry': '银行'},
        {'symbol': '601328.SS', 'symbol_standardized': '601328', 'stock_name': '交通银行', 'industry': '银行'},
        {'symbol': '600031.SS', 'symbol_standardized': '600031', 'stock_name': '三一重工', 'industry': '工程机械'},
        {'symbol': '601668.SS', 'symbol_standardized': '601668', 'stock_name': '中国建筑', 'industry': '建筑装饰'},
        {'symbol': '600019.SS', 'symbol_standardized': '600019', 'stock_name': '宝钢股份', 'industry': '钢铁'},
        {'symbol': '000858.SZ', 'symbol_standardized': '000858', 'stock_name': '五粮液', 'industry': '白酒'}
    ]
    
    # 尝试从数据库获取
    conn = get_db_connection()
    if conn:
        try:
            with conn.cursor() as cursor:
                cursor.execute("SELECT symbol, symbol_standardized, stock_name, industry FROM stock_info ORDER BY stock_name")
                stocks = cursor.fetchall()
                
                # 如果数据库中有数据，返回数据库的数据
                if stocks:
                    return jsonify({"stocks": stocks, "source": "database"})
        except Exception as e:
            print(f"获取所有股票失败: {e}")
        finally:
            conn.close()
    
    # 数据库连接失败或没有数据时，返回备用数据
    print("使用备用股票数据")
    return jsonify({"stocks": fallback_stocks, "source": "fallback"})


@app.route('/api/analysis/status', methods=['GET'])
def get_analysis_status():
    """获取当前分析状态的API端点"""
    return jsonify(analysis_status)


@app.route('/api/stocks', methods=['GET'])
def get_stocks():
    return jsonify({"symbols": config['stock_symbols']})


@app.route('/api/stocks/<symbol>', methods=['GET'])
def analyze_stock(symbol):
    # 处理股票代码格式
    processed_symbol = process_stock_symbol(symbol)
    result = generate_stock_analysis(processed_symbol)
    if "error" in result:
        return jsonify(result), 404
    return jsonify(result)


@app.route('/api/stocks/batch', methods=['POST'])
def analyze_stocks_batch():
    data = request.json
    symbols = data.get('symbols', [])
    results = []

    for symbol in symbols:
        # 处理股票代码格式
        processed_symbol = process_stock_symbol(symbol)
        result = generate_stock_analysis(processed_symbol)
        results.append(result)

    return jsonify({"results": results})


@app.route('/api/stocks/signals', methods=['GET'])
def get_stocks_with_signals():
    """
    获取当天有买入信号或卖出信号的股票，支持分页和排序
    """
    conn = get_db_connection()
    if not conn:
        return jsonify({"error": "数据库连接失败"}), 500
    
    try:
        # 获取分页和排序参数
        page = int(request.args.get('page', 1))
        per_page = int(request.args.get('per_page', 20))
        sort_by = request.args.get('sort_by', 'created_at')
        order = request.args.get('order', 'desc')
        
        # 验证排序字段
        valid_sort_fields = ['symbol', 'stock_name', 'industry', 'created_at']
        if sort_by not in valid_sort_fields:
            sort_by = 'created_at'
        
        # 验证排序方向
        if order not in ['asc', 'desc']:
            order = 'desc'
        
        with conn.cursor() as cursor:
            # 获取当天的分析结果总数
            today = datetime.now().strftime('%Y-%m-%d')
            
            # 首先获取所有符合条件的股票
            # 使用单行SQL语句来避免三引号问题
            cursor.execute("SELECT * FROM stock_analysis_results WHERE DATE(created_at) = %s", (today,))
            
            all_stocks = []
            for row in cursor.fetchall():
                # 解析indicators JSON
                if isinstance(row['indicators'], str):
                    indicators = json.loads(row['indicators'])
                else:
                    indicators = row['indicators']
                
                # 检查是否有买入或卖出信号
                if 'signals' in indicators:
                    has_buy_signal = len(indicators['signals'].get('buy_signals', [])) > 0
                    has_sell_signal = len(indicators['signals'].get('sell_signals', [])) > 0
                    
                    if has_buy_signal or has_sell_signal:
                        all_stocks.append({
                            'symbol': row['symbol'],
                            'stock_name': row['stock_name'],
                            'industry': row['industry'],
                            'has_buy_signal': has_buy_signal,
                            'has_sell_signal': has_sell_signal,
                            'buy_signals': indicators['signals'].get('buy_signals', []),
                            'sell_signals': indicators['signals'].get('sell_signals', []),
                            'latest_price': indicators.get('latest_price'),
                            'created_at': row['created_at'].strftime('%Y-%m-%d %H:%M:%S')
                        })
            
            # 在Python中进行排序
            # 定义排序键函数
            def sort_key(stock):
                if sort_by == 'created_at':
                    return stock[sort_by]
                elif sort_by == 'symbol':
                    return stock[sort_by]
                elif sort_by == 'stock_name':
                    return stock[sort_by]
                elif sort_by == 'industry':
                    return stock[sort_by] or ''
                return stock[sort_by]
            
            # 执行排序
            sorted_stocks = sorted(all_stocks, key=sort_key, reverse=(order == 'desc'))
            
            # 计算分页
            total = len(sorted_stocks)
            start = (page - 1) * per_page
            end = start + per_page
            paginated_stocks = sorted_stocks[start:end]
            
            # 计算总页数
            total_pages = (total + per_page - 1) // per_page
            
            return jsonify({
                "results": paginated_stocks,
                "pagination": {
                    "page": page,
                    "per_page": per_page,
                    "total": total,
                    "total_pages": total_pages,
                    "sort_by": sort_by,
                    "order": order
                }
            })
    except Exception as e:
        print(f"获取信号股票失败: {e}")
        return jsonify({"error": str(e)}), 500
    finally:
        conn.close()


# 主页面
@app.route('/')
def index():
    return render_template('index.html')


if __name__ == '__main__':
    # 确保配置文件存在
    if not os.path.exists(CONFIG_FILE):
        save_config(config)
    
    # 创建数据库表
    create_tables()

    # 启动Flask应用
    app.run(host='0.0.0.0', port=5000, debug=True)
